package ru.spb.osll.myfit.server.execute;

import static org.easymock.EasyMock.expect;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.lang.reflect.Constructor;

import org.easymock.EasyMockSupport;
import org.junit.Before;
import org.junit.Test;

import fit.Parse;
import fitnesse.wiki.WikiPage;

public class FitNesseTestRunnerTest extends EasyMockSupport {

	public class TestableFitNesseTestRunner extends FitNesseTestRunner {

		public TestableFitNesseTestRunner(String rootPath,
				String rootDirectoryName, MyFitFixtureLoader fixtureLoader,
				MyFitFixtureRunner fixtureRunner) throws Exception {
			m_fixtureRunner = fixtureRunner;
			m_fixtureLoader = fixtureLoader;
		}

		public Parse getParse(String pagePath) throws Exception {
			return super.getParse(pagePath);
		}

		@Override
		public WikiPage createRoot(String rootPath, String rootDirectoryName)
				throws Exception {
			return null;
		}
	}

	private static final String HTML_PAGE = "<table border=\"1\" cellspacing=\"0\">"
			+ "<tr><td>Import</td></tr>"
			+ "<tr><td>ru.spb.osll.myfit.fixtures.base</td>"
			+ "</tr></table>"
			+ "<table border=\"1\" cellspacing=\"0\">"
			+ "<tr><td class=\"pass\">dummy one line</td>"
			+ "<td>OK</td></tr></table>";

	private static final String RESULT_HTML = "<table border=\"1\" cellspacing=\"0\">"
			+ "<tr><td>Import</td></tr>"
			+ "<tr><td>ru.spb.osll.myfit.fixtures.base</td></tr>"
			+ "</table>"
			+ "<table border=\"1\" cellspacing=\"0\">"
			+ "<tr><td class=\"pass\" class=\"pass\">dummy one line</td><td>OK</td></tr>"
			+ "</table>";

	private static final String ERROR_RESULT_HTML = "<table border=\"1\" cellspacing=\"0\">"
			+ "<tr><td>Import</td></tr>"
			+ "<tr><td>ru.spb.osll.myfit.fixtures.base</td></tr>"
			+ "</table>"
			+ "<table border=\"1\" cellspacing=\"0\">"
			+ "<tr><td class=\"pass\" class=\"error\">dummy one line<hr><pre><div class=\"fit_stacktrace\">java.lang.Exception: OUPS"
			;

	private FitNesseTestRunner testRunner;
	private MyFitFixtureListener listener;

	@Before
	public void setUp() throws SecurityException, NoSuchMethodException {
		listener = new MyFitFixtureListener();
		MyFitFixtureLoader fixtureLoader = new TestableFixtureLoader();
		MyFitFixtureRunner fixtureRunner = new MyFitFixtureRunner(fixtureLoader, listener);
		Constructor<FitNesseTestRunnerTest.TestableFitNesseTestRunner> constructor = FitNesseTestRunnerTest.TestableFitNesseTestRunner.class
				.getConstructor(FitNesseTestRunnerTest.class, String.class,
						String.class, MyFitFixtureLoader.class,
						MyFitFixtureRunner.class);
		testRunner = createMockBuilder(TestableFitNesseTestRunner.class)
				.withConstructor(constructor)
				.withArgs(this, "path/to/fitnesse", "FitNesseRoot",
						fixtureLoader, fixtureRunner)
				.addMockedMethod("getParse", String.class).createMock();
	}

	@Test
	public void testExecuteTest() throws Exception {
		expect(testRunner.getParse("TestSuite.TestPage")).andReturn(
				new Parse(HTML_PAGE));
		replayAll();
		testRunner.run("TestSuite.TestPage");
		String result = listener.getOutput().replace("&nbsp;", "");
		assertEquals(RESULT_HTML, result);
		verifyAll();
	}

	@Test
	public void testExecuteTestWithException() throws Exception {
		expect(testRunner.getParse("TestSuite.TestPage2")).andStubReturn(
				new Parse(HTML_PAGE.replaceAll("OK", "OUPS")));
		replayAll();
		testRunner.run("TestSuite.TestPage2");
		String result = listener.getOutput().replace("&nbsp;", "");
		verifyAll();
		assertTrue(result.startsWith(ERROR_RESULT_HTML));
	}

}
